package JsonInterface;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.util.DigestUtils;

import com.message.source.SmsSDKDemo;
import com.opensymphony.xwork2.ActionSupport;

import HibernateFacet.DataRecord;
import HibernateFacet.DeviceInformation;
import HibernateFacet.Warning;
import ImplementInterface.ImplementAndroidInterface;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class AndroidFacet extends ActionSupport implements ServletRequestAware, SessionAware {
    public HttpServletRequest request;
    public JSONObject jMap;
    public JSONArray jList;
    public ImplementAndroidInterface IAI;
    public static boolean isCreateSocket = false;
    public static DatagramSocket serverSocket;
    public String result;
    public static List list1 = new ArrayList<Map>();//list ZKP51_A
    public static Map temporary = new HashMap<String, Object>();
    /*
     * public SessionFactory sessionFactory; public SessionFactory
     * getSessionFactory() { return sessionFactory; }
     *
     * public void setSessionFactory(SessionFactory sessionFactory) {
     * this.sessionFactory = sessionFactory; }
     */

    public ImplementAndroidInterface getIAI() {
        return IAI;
    }

    public void setIAI(ImplementAndroidInterface iAI) {
        IAI = iAI;
    }

    public JSONObject getjMap() {
        return jMap;
    }

    public void setjMap(JSONObject jMap) {
        this.jMap = jMap;
    }

    public JSONArray getjList() {
        return jList;
    }

    public void setjList(JSONArray jList) {
        this.jList = jList;
    }

    public void setResult(String result) {
        this.result = result;
    }


    @Override
    public void setSession(Map<String, Object> arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setServletRequest(HttpServletRequest arg0) {
        // TODO Auto-generated method stub
        this.request = arg0;
    }


    public String checkLoginInformation() {

        int i = 0;
        if (!request.getParameter("name").toString().equals("") && !request.getParameter("password").toString().equals("")) {
            try {
                i = IAI.LoginVerified(request.getParameter("name").toString(), request.getParameter("password").toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            Map map = new HashMap<String, Object>();
            if (i == -1) {
                map.put("result", "fail");
                jMap = JSONObject.fromObject(map);
            } else if (i > 0) {
                map.put("result", "success");
                jMap = JSONObject.fromObject(map);
            }
        }
        return SUCCESS;

    }

    public int getUserID() {
        int i = 0;
        if (!request.getParameter("name").toString().equals("") && !request.getParameter("password").toString().equals("")) {
            try {
                i = IAI.LoginVerified(request.getParameter("name").toString(), request.getParameter("password").toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return i;
        } else return -1;
    }

    public String getCostList() {
        int i = getUserID();
        System.out.println("bbbbbbbbbbbbbbbbb" + i);
        try {


            if (i > 0) {
                List list = IAI.GetDevList(i);
                List mList = new ArrayList<Map>();
                int count = 0;
//		 	System.out.println("设备数量："+list.size());
                for (int c = 0; c < list.size(); c++) {
//		 		System.out.println("设备号次数："+c);
                    Map map = new HashMap<String, Object>();
                    int devID = ((DeviceInformation) list.get(c)).getId();
                    String str = ((DeviceInformation) list.get(c)).getSeriesNumber();
                    List list1 = IAI.GetCostList(devID, str);
                    System.out.println("++++++++++++++++++++++++++++++++");

                    System.out.println("++++++++++++++++++++++++++++++++");
                    int total = 0, currentA = 0, voltageA = 0;
                    String status = "";
                    String dateTime = "";
//				System.out.println("设备cost数量："+list1.size());

                    if (list1.size() > 0) {

                        for (int e = 0; e < list1.size(); e++) {
                            double cost = ((DataRecord) list1.get(e)).getCost();
                            total += cost;
                            currentA = ((DataRecord) list1.get(e)).getCurrentA();
                            voltageA = ((DataRecord) list1.get(e)).getVoltageA();
                            status = ((DataRecord) list1.get(e)).getStatus();
                            dateTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                    .format(((DataRecord) list1.get(e)).getDateTime());
                        }

                        count += total;
                        int online_status = IAI.getDeviceOnlineStatus(devID, str);
                        if (!str.equals(null)) {
                            map.put("series", str);
                            float price = (float) total / 10;
                            float currentA_f = (float) currentA / 10;
                            float voltageA_f = (float) voltageA / 10;
                            DecimalFormat decimalFormat = new DecimalFormat("0.0");
                            String p = decimalFormat.format(price);
                            String currentA_str = decimalFormat.format(currentA_f);
                            String voltageA_str = decimalFormat.format(voltageA_f);
                            map.put("cost", p);
                            map.put("currentA", currentA_str);
                            map.put("voltageA", voltageA_str);
                            map.put("status", status);
                            map.put("dateTime", dateTime);
                            map.put("online_status", online_status);
                            mList.add(map);
                        }
                    }//if list1>0 end
                }
                if (count > 0) {
                    Map map = new HashMap<String, Object>();
                    float price = (float) count / 10;
                    DecimalFormat decimalFormat = new DecimalFormat("0.0");
                    String p = decimalFormat.format(price);
                    map.put("calculate", p);
                    mList.add(map);
                }
                jList = JSONArray.fromObject(mList);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String getWarnList() {
        int i = getUserID();
        String startdate = request.getParameter("startdate");
        String stopdate = request.getParameter("stopdate");
        if (i > 0) {
            List list = IAI.GetDevList(i);
            List mList = new ArrayList<Map>();
            int count = 0;
            for (int c = 0; c < list.size(); c++) {


                int devID = ((DeviceInformation) list.get(c)).getId();
                String str = ((DeviceInformation) list.get(c)).getSeriesNumber();

                List list1 = IAI.GetWarningList(devID, str, startdate, stopdate);

                for (int d = 0; d < list1.size(); d++) {

                    int devID1 = ((Warning) list1.get(d)).getDeviceInformation().getId();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
                    String date = sdf.format(((Warning) list1.get(d)).getDateTime());
                    String time = sdf2.format(((Warning) list1.get(d)).getDateTime());
                    String str1 = IAI.getSeries(devID1);
//		      System.out.println(devID1+"--" + date+"=="+time);
                    Map map = new HashMap<String, Object>();
                    Integer type = ((Warning) list1.get(d)).getType();
                    if (!str.equals(null)) {
                        map.put("series", str1);
                        map.put("type", type);
                        map.put("date", date);
                        map.put("time", time);
                        mList.add(map);
                    }
                }
                jList = JSONArray.fromObject(mList);
            }
        }
        return SUCCESS;
    }


    public String submitResult() {
        if (!request.getParameter("series").toString().equals("") && !request.getParameter("status").toString().equals("") && !request.getParameter("cost").toString().equals("") && !request.getParameter("verify").toString().equals("")) {
            List list = IAI.GetDevList(request.getParameter("series").toString());
            int currentA = 0, voltageA = 0;
            if (list.size() > 0) {
                int devID = ((DeviceInformation) list.get(0)).getId();
                String str = request.getParameter("series").toString() + request.getParameter("status").toString() + request.getParameter("cost").toString();

                if (request.getParameter("verify").toString().equals(str)) {
                    try {
                        int cost = Integer.valueOf(request.getParameter("cost").toString());
                        String status = "";
                        if (request.getParameter("status").toString().equals("on")) {
                            status = "合闸";
                        } else if (request.getParameter("status").toString().equals("off")) {
                            status = "分闸";
                        }
                        if (request.getParameter("ia") != null && request.getParameter("va") != null) {
                            currentA = Integer.valueOf(request.getParameter("ia").toString());
                            voltageA = Integer.valueOf(request.getParameter("va").toString());
                        }
                        int i = IAI.addDataRecord(devID, cost, currentA, voltageA, status);
                        if (i > -1) {
                            Map map = new HashMap<String, Object>();
                            map.put("info", "success");
                            jMap = JSONObject.fromObject(map);
                        } else {
                            Map map = new HashMap<String, Object>();
                            map.put("info", "Transaction failed to commit.");
                            jMap = JSONObject.fromObject(map);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    Map map = new HashMap<String, Object>();
                    map.put("ERROR", "comfirm whether perameters are passed to verify?");
                    jMap = JSONObject.fromObject(map);
                }
            }
        }

        return SUCCESS;
    }

    public String collectRequest() {
        if (!request.getParameter("series").toString().equals("") && !request.getParameter("type").toString().equals("") && !request.getParameter("verify").toString().equals("")) {
            List list = IAI.GetDevList(request.getParameter("series").toString());

            if (list.size() > 0) {
                int devID = ((DeviceInformation) list.get(0)).getId();
                String str = request.getParameter("series").toString() + request.getParameter("type").toString();

                if (request.getParameter("verify").toString().equals(str)) {
                    try {
                        int i = IAI.addWarning(devID, request.getParameter("type").toString(), request.getParameter("series").toString());
                        if (i > -1) {
                            Map map = new HashMap<String, Object>();
                            map.put("info", "success");
                            jMap = JSONObject.fromObject(map);
                        } else {
                            Map map = new HashMap<String, Object>();
                            map.put("info", "Transaction failed to commit.");
                            jMap = JSONObject.fromObject(map);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    Map map = new HashMap<String, Object>();
                    map.put("ERROR", "comfirm whether perameters are passed to verify?");
                    jMap = JSONObject.fromObject(map);
                }
            }
        }

        return SUCCESS;
    }

    public String getRegisterNumber() {
        final int random = new Random().nextInt(1000000) + 1;
        final String phone_number = new String(request.getParameter("phone_number"));
        temporary.put(phone_number, random);
        System.out.println("verify of register:" + phone_number + "/" + random);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1500 * 60);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Clean of map:" + phone_number + "/" + random);
                temporary.remove(phone_number);
            }
        }).start();
        SmsSDKDemo d = new SmsSDKDemo();
        d.messageClient(phone_number, random);
        Map map = new HashMap<String, Object>();
        map.put("index", 1);
        jMap = JSONObject.fromObject(map);
        return SUCCESS;
    }

    public String addRegisterMessages() {
        String register_name = request.getParameter("name");
        String register_password = request.getParameter("password");
        String phone_number = request.getParameter("phone_number");
        String verify_number = request.getParameter("verify");
        try {
            if (!temporary.get(phone_number).toString().equals(verify_number)) {
                Map map = new HashMap<String, Object>();
                map.put("event_case", "verify_fail");
                jMap = JSONObject.fromObject(map);
                return SUCCESS;
            }
        } catch (Exception e) {
            Map map = new HashMap<String, Object>();
            map.put("event_case", "NullPointerException");
            jMap = JSONObject.fromObject(map);
            return SUCCESS;
        }
        String str = IAI.UpdateUserInformation(register_name, register_password, phone_number, verify_number);
        if (str.equals("success")) temporary.remove(phone_number);
        Map map = new HashMap<String, Object>();
        map.put("event_case", str);
        jMap = JSONObject.fromObject(map);
        return SUCCESS;
    }

    public String scan() {
        String register_name = request.getParameter("name");
        String register_password = request.getParameter("password");
        String series = request.getParameter("series");
        String str = IAI.AddDevice(register_name, register_password, series);
        Map map = new HashMap<String, Object>();
        map.put("event_case", str);
        jMap = JSONObject.fromObject(map);
        return SUCCESS;

    }

    public String createSocket() {
        System.out.println("hhh1");
        if (!isCreateSocket) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    isCreateSocket = true;
                    // next created TCP successfully
                    new SocketControl();

                }
            }).start();

        } else
            System.out.print("TCP socket is created!");

        return SUCCESS;

    }

    public String createSocketUdp() {

        if (!isCreateSocket) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    isCreateSocket = true;
//				DatagramSocket serverSocket = null;
                    try {
                        serverSocket = new DatagramSocket(20003);// 20003
                        System.out.println("Socket was created with the port 20003!");
                    } catch (SocketException e1) {
                        e1.printStackTrace();
                    }
                    byte[] recvBuf = new byte[100];
                    DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
                    /*serverSocket.receive(recvPacket);
                    System.out.println("FROM:" + recvPacket.getAddress().getHostAddress() + "PORT:" + recvPacket.getPort() + " LENGTH:" + recvPacket.getLength());*/

//				WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
//				ImplementInterface za = (ImplementInterface) context.getBean("interface");
                    while (true) {
                        try {
                            serverSocket.receive(recvPacket);
                            System.out.println("FROM:" + recvPacket.getAddress().getHostAddress() + "PORT:" + recvPacket.getPort() + " LENGTH:" + recvPacket.getLength());
                            System.out.println(new Date().toString());

                            if ((recvPacket.getLength() == 23) && (((int) recvBuf[12] & 0xff) == 0x03)) {
                                int crc = CRC16.getCRC1021(recvBuf, recvPacket.getLength() - 2);
                                if (((crc >> 8 & 0xff) == ((int) recvBuf[23 - 2] & 0xff))
                                        && ((crc & 0xff) == ((int) recvBuf[23 - 1] & 0xff))) {

                                    int d1 = ((int) recvBuf[0] & 0xff) - 0x30;
                                    int d2 = ((int) recvBuf[1] & 0xff) - 0x30;
                                    int d3 = ((int) recvBuf[2] & 0xff) - 0x30;
                                    int d4 = ((int) recvBuf[3] & 0xff) - 0x30;
                                    int d5 = ((int) recvBuf[4] & 0xff) - 0x30;
                                    int d6 = ((int) recvBuf[5] & 0xff) - 0x30;
                                    int d7 = ((int) recvBuf[6] & 0xff) - 0x30;
                                    int d8 = ((int) recvBuf[7] & 0xff) - 0x30;
                                    int d9 = ((int) recvBuf[8] & 0xff) - 0x30;
                                    int d10 = ((int) recvBuf[9] & 0xff) - 0x30;
                                    int d11 = ((int) recvBuf[10] & 0xff) - 0x30;
                                    int d12 = ((int) recvBuf[11] & 0xff) - 0x30;
                                    String address_str = d1 + "" + d2 + "" + d3 + "" + d4 + "" + d5 + "" + d6 + "" + d7 + "" + d8 + "" + d9 + "" + d10 + "" + d11 + "" + d12;
                                    System.out.println("ZKP51_Aaddress:" + address_str);

                                    int current = ((((int) recvBuf[14] & 0xff) << 8) + ((int) recvBuf[15] & 0xff));
                                    int voltage = ((((int) recvBuf[16] & 0xff) << 8) + ((int) recvBuf[17] & 0xff));
                                    int cost = ((((int) recvBuf[18] & 0xff) << 8) + ((int) recvBuf[19] & 0xff));
                                    System.out.println("current*10:" + current + "A");
                                    System.out.println("voltage*10:" + voltage + "V");
                                    System.out.println("cost:" + cost + "w.min");

                                    String status = "";
                                    if (((int) recvBuf[20] & 0xff) == 0x00) {
                                        status = "分闸";
                                    } else if (((int) recvBuf[20] & 0xff) == 0x01) {
                                        status = "合闸";
                                    }
                                    List list = IAI.GetDevList(address_str);
                                    if (list.size() > 0) {
                                        int devID = ((DeviceInformation) list.get(0)).getId();
                                        int i = IAI.add_UDP_DataRecord(devID, cost, current, voltage, status);
                                        if (i > -1) {
                                            Map map = new HashMap<String, Object>();
                                            map.put("info", "udp_success");
                                            jMap = JSONObject.fromObject(map);
                                        } else {
                                            Map map = new HashMap<String, Object>();
                                            map.put("info", "Transaction failed to commit.");
                                            jMap = JSONObject.fromObject(map);
                                        }

                                    }
                                    Map map = new HashMap<String, Object>();
                                    map.put("IP", recvPacket.getAddress().getHostAddress());
                                    map.put("PORT", recvPacket.getPort());
                                    map.put("address", address_str);

                                    if (list1.size() == 0) {
                                        list1.add(map);
                                    } else {
                                        for (int i = 0; i < list1.size(); i++) {
                                            Map mapx = (Map) list1.get(i);
                                            if (mapx.get("address").equals(map.get("address"))) {
                                                list1.remove(i);
                                            }
                                        }
                                        list1.add(map);
                                    }
                                    Thread.sleep(1000);
                                    byte[] buf = new byte[]{(byte) 0x03, (byte) 0x4f, (byte) 0x4b};
                                    SocketAddress sk = new InetSocketAddress(recvPacket.getAddress().getHostAddress(),
                                            recvPacket.getPort());
                                    DatagramPacket packet = new DatagramPacket(buf, buf.length, sk);
                                    serverSocket.send(packet);

                                }
                            }
                            if ((recvPacket.getLength() == 18) && (((int) recvBuf[12] & 0xff) == 0x04)) {
                                int crc = CRC16.getCRC1021(recvBuf, recvPacket.getLength() - 2);
                                if (((crc >> 8 & 0xff) == ((int) recvBuf[18 - 2] & 0xff))
                                        && ((crc & 0xff) == ((int) recvBuf[18 - 1] & 0xff))) {

                                    int d1 = ((int) recvBuf[0] & 0xff) - 0x30;
                                    int d2 = ((int) recvBuf[1] & 0xff) - 0x30;
                                    int d3 = ((int) recvBuf[2] & 0xff) - 0x30;
                                    int d4 = ((int) recvBuf[3] & 0xff) - 0x30;
                                    int d5 = ((int) recvBuf[4] & 0xff) - 0x30;
                                    int d6 = ((int) recvBuf[5] & 0xff) - 0x30;
                                    int d7 = ((int) recvBuf[6] & 0xff) - 0x30;
                                    int d8 = ((int) recvBuf[7] & 0xff) - 0x30;
                                    int d9 = ((int) recvBuf[8] & 0xff) - 0x30;
                                    int d10 = ((int) recvBuf[9] & 0xff) - 0x30;
                                    int d11 = ((int) recvBuf[10] & 0xff) - 0x30;
                                    int d12 = ((int) recvBuf[11] & 0xff) - 0x30;
                                    String address_str = d1 + "" + d2 + "" + d3 + "" + d4 + "" + d5 + "" + d6 + "" + d7 + "" + d8 + "" + d9 + "" + d10 + "" + d11 + "" + d12;
                                    System.out.println("ZKP51_Aaddress:" + address_str);

                                    String status = "";
                                    if (((int) recvBuf[14] & 0xff) == 0x00) {
                                        status = "分闸";
                                    } else if (((int) recvBuf[14] & 0xff) == 0x01) {
                                        status = "合闸";
                                    }

                                    String warning_type = String.valueOf((int) recvBuf[15] & 0xff);
                                    List list = IAI.GetDevList(address_str);
                                    if (list.size() > 0) {
                                        int devID = ((DeviceInformation) list.get(0)).getId();

                                        IAI.changeStatus(devID, status);
                                        System.out.println("状态改变为:" + status);
                                        if (warning_type.equals("1") || warning_type.equals("2")) {

                                            int i = IAI.addWarning(devID, warning_type, address_str);
                                            System.out.println("故障类型为:" + warning_type);
                                            if (i > -1) {
                                                Map map = new HashMap<String, Object>();
                                                map.put("info", "udp_warning_success");
                                                jMap = JSONObject.fromObject(map);
                                            } else {
                                                Map map = new HashMap<String, Object>();
                                                map.put("info", "Transaction failed to commit.");
                                                jMap = JSONObject.fromObject(map);
                                            }
                                        }

                                    }

                                    Thread.sleep(1000);
                                    byte[] buf = new byte[]{(byte) 0x04, (byte) 0x4f, (byte) 0x4b};
                                    SocketAddress sk = new InetSocketAddress(recvPacket.getAddress().getHostAddress(),
                                            recvPacket.getPort());
                                    DatagramPacket packet = new DatagramPacket(buf, buf.length, sk);
                                    serverSocket.send(packet);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        } else
            System.out.print(" socketudp is failed!");
        return SUCCESS;
    }

    public String controlZKP51() {
        try {
            String address_str = request.getParameter("address");
            Map map = new HashMap<String, Object>();
            System.out.println("address:" + address_str);
            if (!address_str.equals(null)) {
//		System.out.println("controlZKP51");
                for (int i = 0; i < list1.size(); i++) {
                    Map mapx = (Map) list1.get(i);
                    if (mapx.get("address").equals(address_str)) {
                        map = mapx;
                    }
                }
            }
            if (!address_str.equals(null)) {
//		System.out.println("controlZKP51 2");
                int port = map.get("PORT").hashCode();
                char[] c = address_str.toCharArray();
                byte[] a = new byte[c.length];
                for (int i = 0; i < c.length; i++) {
                    a[i] = (byte) (c[i] - '0' + 0x30);
                }
                byte[] buf = new byte[]{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], (byte) 0x10, (byte) 0x01, (byte) 0x20, 0, 0};
//		System.out.println("controlZKP51 3");
                int crc = CRC16.getCRC1021(buf, buf.length - 2);
                int ch = (int) (crc >> 8) & 0xff;
                int cl = (int) crc & 0xff;
                buf[buf.length - 2] = (byte) ch;
                buf[buf.length - 1] = (byte) cl;
                String ip = map.get("IP").toString();
//		          System.out.println(map.get("IP").hashCode());
                System.out.println(map.get("PORT").hashCode());
                SocketAddress sk = new InetSocketAddress(ip, port);
                DatagramPacket packet = new DatagramPacket(buf, buf.length, sk);
                AndroidFacet.serverSocket.send(packet);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        result = SUCCESS;
        return SUCCESS;
    }

    public String getControlPassword() {
        String address_str = request.getParameter("address_str");
        List list = IAI.getControlPassword(address_str);
        result = JSONArray.fromObject(list).toString();
        return SUCCESS;
    }

    public String verifyControlPassword() {
        String address_str = request.getParameter("address_str");
        String control_password = request.getParameter("control_password");
        List list = IAI.verifyControlPassword(address_str, control_password);
        result = JSONArray.fromObject(list).toString();
        return SUCCESS;
    }

    public String updateControlPassword() {
        String address_str = request.getParameter("address_str");
        String new_control_password = request.getParameter("new_control_password");
        List list = IAI.updateControlPassword(address_str, new_control_password);
        result = JSONArray.fromObject(list).toString();
        return SUCCESS;
    }

}
